package com.example.ole.taskqueue.Q.base;

import com.example.ole.taskqueue.Print;

import java.util.List;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class XTaskQueue implements RejectedExecutionHandler {
    public String TAG = "XTaskQueue";
    public int CAPACITY = 5;
    private XExecutor mPool;
    private PrioritizedRecordingQueue<XTask> mTaskQueue;
    private final int mCameraFacingId;

    public XTaskQueue(int cameraFacingId) {
        mCameraFacingId = cameraFacingId;
    }

    public boolean start() {
        Print.d(mCameraFacingId, 1, TAG, "Starting.");
        mTaskQueue = new PrioritizedRecordingQueue<>(CAPACITY);
        mPool = new XExecutor(0, 1, 0L, TimeUnit.MILLISECONDS, mTaskQueue, this); //Do NOT change any parameter. Or everything will not work.

        return true;
    }

    /**
     * @param dropPendingTasks False for async stopping, True for sync stopping.
     * @param timeoutMs        timeout in milliseconds for async stopping.
     * @return false on timeout.
     */
    public boolean stop(boolean dropPendingTasks, long timeoutMs) {
        if (dropPendingTasks) {
            List<Runnable> dropped = mPool.shutdownNow();
            Print.d(mCameraFacingId, 1, TAG, "Stopping. Dropped " + dropped.size() + " pending tasks.");
        } else {
            mPool.shutdown();
            Print.d(mCameraFacingId, 1, TAG, "Stopping.");
        }
        // some task can not be interrupted, but we can user progress controller to let it break.
        try {
            return mPool.awaitTermination(timeoutMs, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
            return false;
        }
    }

    public void addTask(XTask rt) {
        mPool.execute(rt);
    }

    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        XTask rt = (XTask) r;
        Print.e(mCameraFacingId, TAG, mPool.toString());
        Print.e(mCameraFacingId, TAG, "[SD Performance] XTask " + rt.identity() + " was rejected for queue only support " + CAPACITY + " tasks.");
    }
}
